/*
 * temp.java
 *
 * Created on May 30, 2007, 9:58 PM
 */

package bbdSwing;

/*
 * Copyright 2007 microneering, Inc and James Gamber
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 * 
 * BBD/bbdSwing/BBDCrudPanel.java
 */
import javax.swing.JOptionPane;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.DefaultTableColumnModel;
import javax.swing.table.DefaultTableModel;

public class BBDCrudPanel extends javax.swing.JPanel implements
		TableModelListener, ListSelectionListener {

	/**
	 * 
	 */
	private static final long serialVersionUID = -3874449002156212951L;

	private final BBDJTable table;

	private final DefaultTableModel model;

	private final ListSelectionModel selectionModel;

	private final DefaultTableColumnModel columnModel;

	private String search = "";

	private final Object[] originalData;

	/**
	 * Creates new form BBDCrudPanel
	 * 
	 * @param table
	 *            This table must be initialized with its BBD broker class and
	 *            will auto populate.
	 */
	public BBDCrudPanel(BBDJTable table) {

		super();

		this.table = table;
		this.model = (DefaultTableModel) table.getModel();
		this.selectionModel = table.getSelectionModel();
		this.columnModel = (DefaultTableColumnModel) table.getColumnModel();

		originalData = new Object[model.getRowCount()];
		this.model.getDataVector().copyInto(originalData);

		initComponents();

		setEdit();

		dataScrollPanel.setViewportView(table);

		this.model.addTableModelListener(this);
		this.selectionModel.addListSelectionListener(this);

	}

	private void setStatus(String statusMsg) {
		status.setText(statusMsg);
	}

	private void setEdit() {
		changeButton.setEnabled(editButton.isSelected() && table.isDirty());
		discardButton.setEnabled(editButton.isSelected() && table.isDirty());
		addButton.setEnabled(editButton.isSelected());
	}

	/**
	 * This method is called from within the constructor to initialize the form.
	 * WARNING: Do NOT modify this code. The content of this method is always
	 * regenerated by the Form Editor.
	 */
	// <editor-fold defaultstate="collapsed" desc=" Generated Code
	// <editor-fold defaultstate="collapsed" desc=" Generated Code
	// ">//GEN-BEGIN:initComponents
	private void initComponents() {

		dataPanel = new javax.swing.JPanel();
		dataScrollPanel = new javax.swing.JScrollPane();
		controlPanel = new javax.swing.JPanel();
		status = new javax.swing.JLabel();
		editButton = new javax.swing.JToggleButton();
		changeButton = new javax.swing.JButton();
		discardButton = new javax.swing.JButton();
		firstButton = new javax.swing.JButton();
		lastButton = new javax.swing.JButton();
		searchButton = new javax.swing.JButton();
		deleteButton = new javax.swing.JButton();
		jSeparator2 = new javax.swing.JSeparator();
		jSeparator3 = new javax.swing.JSeparator();
		addButton = new javax.swing.JButton();

		dataPanel.setBorder(javax.swing.BorderFactory
				.createBevelBorder(javax.swing.border.BevelBorder.LOWERED));

		javax.swing.GroupLayout dataPanelLayout = new javax.swing.GroupLayout(
				dataPanel);
		dataPanel.setLayout(dataPanelLayout);
		dataPanelLayout.setHorizontalGroup(dataPanelLayout.createParallelGroup(
				javax.swing.GroupLayout.Alignment.LEADING).addComponent(
				dataScrollPanel, javax.swing.GroupLayout.Alignment.TRAILING,
				javax.swing.GroupLayout.DEFAULT_SIZE, 918, Short.MAX_VALUE));
		dataPanelLayout.setVerticalGroup(dataPanelLayout.createParallelGroup(
				javax.swing.GroupLayout.Alignment.LEADING).addComponent(
				dataScrollPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 368,
				javax.swing.GroupLayout.PREFERRED_SIZE));

		controlPanel.setBorder(javax.swing.BorderFactory
				.createBevelBorder(javax.swing.border.BevelBorder.RAISED));

		status.setFont(new java.awt.Font("Tahoma", 1, 13));
		status.setText("Initialized");

		editButton.setText("Edit");
		editButton.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				editButtonActionPerformed(evt);
			}
		});

		changeButton.setText("Apply Changes");
		changeButton.setEnabled(false);
		changeButton.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				changeButtonActionPerformed(evt);
			}
		});

		discardButton.setText("Discard Changes");
		discardButton.setEnabled(false);
		discardButton.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				discardButtonActionPerformed(evt);
			}
		});

		firstButton.setText("First");
		firstButton.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				firstButtonActionPerformed(evt);
			}
		});

		lastButton.setText("Last");
		lastButton.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				lastButtonActionPerformed(evt);
			}
		});

		searchButton.setText("Search");
		searchButton.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				searchButtonActionPerformed(evt);
			}
		});

		deleteButton.setText("Delete");
		deleteButton.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				deleteButtonActionPerformed(evt);
			}
		});
		deleteButton.setEnabled(false);

		jSeparator2.setOrientation(javax.swing.SwingConstants.VERTICAL);
		jSeparator2.setPreferredSize(new java.awt.Dimension(5, 30));

		jSeparator3.setOrientation(javax.swing.SwingConstants.VERTICAL);
		jSeparator3.setPreferredSize(new java.awt.Dimension(5, 30));

		addButton.setText("Add");
		addButton.setEnabled(false);
		addButton.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				addButtonActionPerformed(evt);
			}
		});

		javax.swing.GroupLayout controlPanelLayout = new javax.swing.GroupLayout(
				controlPanel);
		controlPanel.setLayout(controlPanelLayout);
		controlPanelLayout
				.setHorizontalGroup(controlPanelLayout
						.createParallelGroup(
								javax.swing.GroupLayout.Alignment.LEADING)
						.addGroup(
								controlPanelLayout
										.createSequentialGroup()
										.addGap(41, 41, 41)
										.addGroup(
												controlPanelLayout
														.createParallelGroup(
																javax.swing.GroupLayout.Alignment.LEADING)
														.addComponent(
																status,
																javax.swing.GroupLayout.PREFERRED_SIZE,
																847,
																javax.swing.GroupLayout.PREFERRED_SIZE)
														.addGroup(
																controlPanelLayout
																		.createSequentialGroup()
																		.addComponent(
																				editButton,
																				javax.swing.GroupLayout.PREFERRED_SIZE,
																				108,
																				javax.swing.GroupLayout.PREFERRED_SIZE)
																		.addGap(
																				18,
																				18,
																				18)
																		.addComponent(
																				jSeparator2,
																				javax.swing.GroupLayout.PREFERRED_SIZE,
																				5,
																				javax.swing.GroupLayout.PREFERRED_SIZE)
																		.addGap(
																				18,
																				18,
																				18)
																		.addComponent(
																				changeButton,
																				javax.swing.GroupLayout.PREFERRED_SIZE,
																				106,
																				javax.swing.GroupLayout.PREFERRED_SIZE)
																		.addPreferredGap(
																				javax.swing.LayoutStyle.ComponentPlacement.RELATED)
																		.addComponent(
																				discardButton)
																		.addPreferredGap(
																				javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
																		.addComponent(
																				addButton,
																				javax.swing.GroupLayout.PREFERRED_SIZE,
																				75,
																				javax.swing.GroupLayout.PREFERRED_SIZE)
																		.addPreferredGap(
																				javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
																		.addComponent(
																				deleteButton)
																		.addPreferredGap(
																				javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
																		.addComponent(
																				jSeparator3,
																				javax.swing.GroupLayout.PREFERRED_SIZE,
																				5,
																				javax.swing.GroupLayout.PREFERRED_SIZE)
																		.addGap(
																				14,
																				14,
																				14)
																		.addComponent(
																				firstButton)
																		.addGap(
																				18,
																				18,
																				18)
																		.addComponent(
																				lastButton)
																		.addGap(
																				18,
																				18,
																				18)
																		.addComponent(
																				searchButton)))
										.addContainerGap(
												javax.swing.GroupLayout.DEFAULT_SIZE,
												Short.MAX_VALUE)));
		controlPanelLayout
				.setVerticalGroup(controlPanelLayout
						.createParallelGroup(
								javax.swing.GroupLayout.Alignment.LEADING)
						.addGroup(
								controlPanelLayout
										.createSequentialGroup()
										.addGap(11, 11, 11)
										.addGroup(
												controlPanelLayout
														.createParallelGroup(
																javax.swing.GroupLayout.Alignment.LEADING)
														.addComponent(
																changeButton)
														.addComponent(
																discardButton)
														.addComponent(
																deleteButton)
														.addComponent(addButton))
										.addPreferredGap(
												javax.swing.LayoutStyle.ComponentPlacement.RELATED,
												19, Short.MAX_VALUE)
										.addComponent(status).addContainerGap())
						.addGroup(
								controlPanelLayout
										.createSequentialGroup()
										.addGap(11, 11, 11)
										.addComponent(
												jSeparator3,
												javax.swing.GroupLayout.PREFERRED_SIZE,
												javax.swing.GroupLayout.DEFAULT_SIZE,
												javax.swing.GroupLayout.PREFERRED_SIZE)
										.addContainerGap(39, Short.MAX_VALUE))
						.addGroup(
								controlPanelLayout
										.createSequentialGroup()
										.addGap(11, 11, 11)
										.addComponent(
												jSeparator2,
												javax.swing.GroupLayout.PREFERRED_SIZE,
												javax.swing.GroupLayout.DEFAULT_SIZE,
												javax.swing.GroupLayout.PREFERRED_SIZE)
										.addContainerGap(39, Short.MAX_VALUE))
						.addGroup(
								controlPanelLayout.createSequentialGroup()
										.addGap(11, 11, 11).addComponent(
												editButton).addContainerGap(46,
												Short.MAX_VALUE))
						.addGroup(
								controlPanelLayout
										.createSequentialGroup()
										.addContainerGap()
										.addGroup(
												controlPanelLayout
														.createParallelGroup(
																javax.swing.GroupLayout.Alignment.LEADING)
														.addComponent(
																searchButton)
														.addGroup(
																controlPanelLayout
																		.createParallelGroup(
																				javax.swing.GroupLayout.Alignment.BASELINE)
																		.addComponent(
																				firstButton)
																		.addComponent(
																				lastButton)))
										.addGap(46, 46, 46)));

		javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
		this.setLayout(layout);
		layout.setHorizontalGroup(layout.createParallelGroup(
				javax.swing.GroupLayout.Alignment.LEADING).addComponent(
				dataPanel, javax.swing.GroupLayout.DEFAULT_SIZE,
				javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
				.addGroup(
						layout.createSequentialGroup().addGap(10, 10, 10)
								.addComponent(controlPanel,
										javax.swing.GroupLayout.DEFAULT_SIZE,
										javax.swing.GroupLayout.DEFAULT_SIZE,
										Short.MAX_VALUE).addGap(10, 10, 10)));
		layout.setVerticalGroup(layout.createParallelGroup(
				javax.swing.GroupLayout.Alignment.LEADING).addGroup(
				layout.createSequentialGroup().addComponent(dataPanel,
						javax.swing.GroupLayout.PREFERRED_SIZE,
						javax.swing.GroupLayout.DEFAULT_SIZE,
						javax.swing.GroupLayout.PREFERRED_SIZE).addGap(18, 18,
						18).addComponent(controlPanel,
						javax.swing.GroupLayout.DEFAULT_SIZE,
						javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
						.addContainerGap()));
	}// </editor-fold>//GEN-END:initComponents

	private void addButtonActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_addButtonActionPerformed
		table.addNewRow();
	}// GEN-LAST:event_addButtonActionPerformed

	private void lastButtonActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_lastButtonActionPerformed
		int lastRow = table.getRowCount() - 1;
		table.getSelectionModel().setSelectionInterval(lastRow, lastRow);
		setStatus("Last Row Selected");
	}// GEN-LAST:event_lastButtonActionPerformed

	private void firstButtonActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_firstButtonActionPerformed
		selectionModel.setSelectionInterval(0, 0);
		setStatus("First Row Selected");
	}// GEN-LAST:event_firstButtonActionPerformed

	private void discardButtonActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_discardButtonActionPerformed

		table.populate();
		
		editButton.setSelected(false);
		
		setEdit();

		setStatus("Changes discarded");

	}// GEN-LAST:event_discardButtonActionPerformed

	private void changeButtonActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_changeButtonActionPerformed
		
		int rows = table.persist();
		
		setEdit();
		
		setStatus("Rows affected "+rows);
		
	}// GEN-LAST:event_changeButtonActionPerformed

	private void editButtonActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_editButtonActionPerformed

		if (editButton.isSelected()) {
			table.setEnabled(true);
			setStatus("Click on any item to edit it");
		} else {
			table.setEnabled(false);
			table.clearSelection();
			setStatus("Editing done");
		}

		setEdit();

		int rows = model.getRowCount();
		int cols = model.getColumnCount();
		boolean alreadyHaveEmptyRowOnEnd = true;
		for (int c = 0; c < cols; c++) {
			if (model.getValueAt(rows - 1, c) != "") {
				alreadyHaveEmptyRowOnEnd = false;
				break;
			}
		}

		if (!alreadyHaveEmptyRowOnEnd) {
			table.addNewRow();
		}

	}// GEN-LAST:event_editButtonActionPerformed

	private void searchButtonActionPerformed(java.awt.event.ActionEvent evt) {

		search = (String) JOptionPane.showInputDialog(this,
				"Enter search text", "Search", JOptionPane.QUESTION_MESSAGE,
				null, null, search);
		final int rows = model.getRowCount();
		final int cols = model.getColumnCount();
		int selectedRow = selectionModel.getMaxSelectionIndex() + 1;
		if (selectedRow < 0 || selectedRow >= rows - 1)
			selectedRow = 0;

		for (int r = selectedRow; r < rows; r++) {
			for (int c = 0; c < cols; c++) {
				if (((String) model.getValueAt(r, c)).toUpperCase().indexOf(
						search.toUpperCase()) > -1) {
					selectionModel.setSelectionInterval(r, r);
					setStatus("Search found "+search);
					return;
				}
			}
		}
	}

	@SuppressWarnings("unused")
	private void deleteButtonActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_deleteButtonActionPerformed

		int removed = table.removeSelected();

		setStatus("Row(s) deleted "+removed );

		setEdit();

	}// GEN-LAST:event_deleteButtonActionPerformed

	// Variables declaration - do not modify//GEN-BEGIN:variables
	private javax.swing.JButton changeButton;

	private javax.swing.JPanel controlPanel;

	private javax.swing.JPanel dataPanel;

	private javax.swing.JScrollPane dataScrollPanel;

	private javax.swing.JButton discardButton;

	private javax.swing.JToggleButton editButton;

	private javax.swing.JButton firstButton;

	private javax.swing.JButton deleteButton;

	private javax.swing.JButton addButton;

	private javax.swing.JSeparator jSeparator2;

	private javax.swing.JSeparator jSeparator3;

	private javax.swing.JButton lastButton;

	private javax.swing.JButton searchButton;

	private javax.swing.JLabel status;

	// End of variables declaration//GEN-END:variables

	public void tableChanged(TableModelEvent e) {

		final int col = e.getColumn();
		final int row = e.getFirstRow();

		if (col == -1)
			return;

		setEdit();

		setStatus("Row " + row + " column "
				+ columnModel.getColumn(col).getHeaderValue() + " changed");

	}

	public void valueChanged(ListSelectionEvent e) {

		if (editButton.isSelected())
			deleteButton.setEnabled(table.getSelectedRowCount() > 0);

	}

}
